package com.sduept.nwld.dataserver.controller.equipment.assessment;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.primefaces.event.SelectEvent;
import org.springframework.beans.factory.annotation.Autowired;

import com.sduept.bigdata.equipment.assessment.exception.ParameterException;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionItem;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionPlan;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionStation;
import com.sduept.bigdata.equipment.assessment.service.InspectionPlanService;
import com.sduept.bigdata.equipment.assessment.service.InspectionStationService;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.ledger.manager.SubstationLedgerManager;
import com.sduept.nwld.dataserver.service.equipment.assessment.InspectionPlanProgressService;
import com.sduept.utils.PingYinUtil;

/**
 * 评价进度管理页面controller
 * @author huangyu
 * @Date 2019年8月15日
 */
@Named
@ViewScoped
public class InspectionPlanProgressController extends AbstractController {
	
	private static final long serialVersionUID = -746127546025033941L;
	
	@Autowired
	private InspectionPlanService planService;
	@Autowired
	private InspectionStationService stationService;
	@Autowired
	private SubstationLedgerManager ledgerM;
	@Autowired
	private InspectionPlanProgressService progressService;
	/**
	 * 所有的评价计划
	 */
	private List<InspectionPlan> plans;
	/**
	 * 为优化页面展示所封装的dto
	 */
	private PlanDetailDTO planDto = new PlanDetailDTO();
	/**
	 * 当查看某个计划时，先从map中查找所需展示的信息，没有时才从库中读取
	 */
	private Map<InspectionPlan,PlanDetailDTO> planMap = new HashMap<InspectionPlan, PlanDetailDTO>();

	private List<InspectionStationDTO> allStationDtos = new ArrayList<InspectionStationDTO>();
	private List<InspectionStationDTO> finishStationDtos = new ArrayList<InspectionStationDTO>();
	private List<InspectionStationDTO> unfinishStationDtos = new ArrayList<InspectionStationDTO>();
	
	@PostConstruct
	public void init() {
		plans = planService.findAll();
		if(0 != plans.size()) {
			InspectionPlan selectedPlan = plans.get(0);
			genPlanDTO(selectedPlan);
			getDiffStatusStation();
		}
	}
	/**
	 * 按照供电局的完成情况进行分组
	 */
	private void getDiffStatusStation() {
		Map<String, List<InspectionStationDTO>> finishiMap = planDto.getAcceptUnitFinishMap();
		for (String unit : finishiMap.keySet()) {
			finishStationDtos.addAll(finishiMap.get(unit));
		}
		Map<String, List<InspectionStationDTO>> unFinishiMap = planDto.getAcceptUnitUnfinishMap();
		for (String unit : unFinishiMap.keySet()) {
			unfinishStationDtos.addAll(unFinishiMap.get(unit));
		}
		allStationDtos.addAll(finishStationDtos);
		allStationDtos.addAll(unfinishStationDtos);
	}
	/**
	 * 按照当前计划，生成页面需要展示的DTO
	 * @param plan
	 */
	private void genPlanDTO(InspectionPlan plan) {
		if(!planMap.keySet().contains(plan)) {
			PlanDetailDTO dto = new PlanDetailDTO();
			genPlanDTOStation(plan,dto);
			planMap.put(plan, dto);
		}
		planDto = planMap.get(plan);
	}
	
	/**
	 * 生成页面展示所用的评价计划dto的变电站信息部分
	 * @param plan
	 * @param dto
	 * @return 
	 */
	private void genPlanDTOStation(InspectionPlan plan,PlanDetailDTO dto) {
		try {
			// 有权限查看的变电站及其评价项目
			Map<InspectionStation, List<InspectionItem>> map = progressService.findInspectionStations(plan, getCurrentUser());
			
			Map<String,List<InspectionStation>> acceptUnitAndStationMap = transStationDtoMapToAcceptUnitMap(map);
			
			Map<String,List<InspectionStationDTO>> acceptUnitAllMap = new HashMap<String, List<InspectionStationDTO>>();
			Map<String,List<InspectionStationDTO>> acceptUnitFinishMap = new HashMap<String, List<InspectionStationDTO>>();
			Map<String,List<InspectionStationDTO>> acceptUnitUnfinishMap = new HashMap<String, List<InspectionStationDTO>>();
			for (String unit : acceptUnitAndStationMap.keySet()) {
				List<InspectionStation> stations = acceptUnitAndStationMap.get(unit);
				boolean flag = false;
				List<InspectionStationDTO> lt = new ArrayList<InspectionStationDTO>();
				for (InspectionStation station : stations) {
					List<InspectionItem> items = map.get(station);
					InspectionStationDTO stationDto = genInspectionStationDTO(station,items);
					lt.add(stationDto);
					// 0：未开始 1：进行中 2：已完成
					if(2 == station.getStatus()) {
						flag = true;
					}
				}
				if(flag) {
					acceptUnitFinishMap.put(unit, lt);
				} else {
					acceptUnitUnfinishMap.put(unit, lt);
				}
				acceptUnitAllMap.put(unit, lt);
			}
			dto.setAcceptUnitAllMap(acceptUnitAllMap);
			dto.setAcceptUnitFinishMap(acceptUnitFinishMap);
			dto.setAcceptUnitUnfinishMap(acceptUnitUnfinishMap);
			float planRatio = getRatio(acceptUnitFinishMap.keySet().size(), acceptUnitAllMap.keySet().size());
			dto.setFinishRatio(planRatio);
			dto.setPlan(plan);
		} catch (ParameterException e) {
			e.printStackTrace();
			addErrorMessage("获取计划的检查站以及检查项目出错");
		}
	}
	/**
	 * 将变电站按照AcceptUnit进行分组
	 * @param map
	 * @return
	 */
	private Map<String, List<InspectionStation>> transStationDtoMapToAcceptUnitMap(Map<InspectionStation, List<InspectionItem>> map) {
		Map<String,List<InspectionStation>> acceptUnitAndStationMap = new HashMap<String, List<InspectionStation>>();
		for (InspectionStation station : map.keySet()) {
			String acceptUnit = station.getAcceptUnit();
			List<InspectionStation> lt = acceptUnitAndStationMap.get(acceptUnit);
			if(null == lt) {
				lt = new ArrayList<InspectionStation>();
			}
			lt.add(station);
			acceptUnitAndStationMap.put(acceptUnit, lt);
		}
		return acceptUnitAndStationMap;
	}
	
	/**
	 * 根据分子、分母获取比率，保留两位小数
	 * @param numerator
	 * @param denominator
	 * @return 
	 */
	private float getRatio(int numerator,int denominator) {
		String ratio;
		DecimalFormat df = new DecimalFormat("#0.000");
		if(0 == denominator) {
			ratio = "0";
		} else {
			double result = (float)numerator/(float)denominator;
			ratio = df.format(result);
		}
		return Float.parseFloat(ratio);
	}
	
	/**
	 * 为方便展示某个变电站的评价详情，将评价站、及其评价项目封装为dto
	 * @param station
	 * @param itemsDto
	 * @return
	 */
	private InspectionStationDTO genInspectionStationDTO(InspectionStation station,List<InspectionItem> items) {
		InspectionStationDTO dto = new InspectionStationDTO();
		dto.setStation(station);
		int unfinishedItemCount = 0;
		int finishedItemCount = 0;
		for (InspectionItem item : items) {
			// 0：未完成； 1：已完成
			if(0 == item.getStatus()) {
				unfinishedItemCount++;
			} else if (1 == item.getStatus()) {
				finishedItemCount++;
			}
		}
		float finishRate = getRatio(finishedItemCount,finishedItemCount+unfinishedItemCount);
		dto.setAllItemCount(finishedItemCount+unfinishedItemCount);
		dto.setFinishedItemCount(finishedItemCount);
		dto.setUnfinishedItemCount(unfinishedItemCount);
		dto.setFinishRate(finishRate);
		return dto;
	}
	
	/**
	 * 查看的计划变化时，同步修改页面显示的数据
	 * @param event
	 */
	public void changeSelectPlan(SelectEvent event) {
		allStationDtos = new ArrayList<InspectionStationDTO>();
		finishStationDtos = new ArrayList<InspectionStationDTO>();
		unfinishStationDtos = new ArrayList<InspectionStationDTO>();
		planDto = new PlanDetailDTO();
		String planId = (String) event.getObject();
		InspectionPlan selectedPlan = planService.findById(planId);
		genPlanDTO(selectedPlan);
		getDiffStatusStation();
	}
	
	/**
	 * 计划查询下拉列表
	 * @param query
	 * @return
	 */
	public List<InspectionPlan> complateInspectionPlan(String query) {
		List<InspectionPlan> result = new ArrayList<InspectionPlan>();
		for (InspectionPlan plan : plans) {
			String nameHead = PingYinUtil.getPingYinHeader(plan.getName());
			if (nameHead.toLowerCase().contains(query)) {
				result.add(plan);
			}
		}
		return result;
	}
	
	public class PlanDetailDTO {
		/**
		 * 当前查看的评价计划
		 */
		private InspectionPlan plan;
		/**
		 * 计划完成率
		 */
		private float finishRatio;
		/**
		 * 供电局总数
		 */
		private Map<String,List<InspectionStationDTO>> acceptUnitAllMap;
		/**
		 * 已完成供电局
		 */
		private Map<String,List<InspectionStationDTO>> acceptUnitFinishMap;
		/**
		 * 未完成供电局
		 */
		private Map<String,List<InspectionStationDTO>> acceptUnitUnfinishMap;
		
		public InspectionPlan getPlan() {
			return plan;
		}
		public float getFinishRatio() {
			return finishRatio;
		}
		public void setPlan(InspectionPlan plan) {
			this.plan = plan;
		}
		public void setFinishRatio(float finishRatio) {
			this.finishRatio = finishRatio;
		}
		public Map<String, List<InspectionStationDTO>> getAcceptUnitAllMap() {
			return acceptUnitAllMap;
		}
		public Map<String, List<InspectionStationDTO>> getAcceptUnitFinishMap() {
			return acceptUnitFinishMap;
		}
		public Map<String, List<InspectionStationDTO>> getAcceptUnitUnfinishMap() {
			return acceptUnitUnfinishMap;
		}
		public void setAcceptUnitAllMap(Map<String, List<InspectionStationDTO>> acceptUnitAllMap) {
			this.acceptUnitAllMap = acceptUnitAllMap;
		}
		public void setAcceptUnitFinishMap(Map<String, List<InspectionStationDTO>> acceptUnitFinishMap) {
			this.acceptUnitFinishMap = acceptUnitFinishMap;
		}
		public void setAcceptUnitUnfinishMap(Map<String, List<InspectionStationDTO>> acceptUnitUnfinishMap) {
			this.acceptUnitUnfinishMap = acceptUnitUnfinishMap;
		}
	}
	
	/**
	 * 将变电站的已完成、未完成的检查项目封装为DTO，用于表格展示
	 * @author huangyu
	 * @Date 2019年8月20日
	 */
	public class InspectionStationDTO {
		/**
		 * 变电站
		 */
		private InspectionStation station;
		/**
		 * 未完成检查项目数量
		 */
		private Integer unfinishedItemCount;
		/**
		 * 已完成检查项目数量
		 */
		private Integer finishedItemCount;
		/**
		 * 所有的检查项目数量
		 */
		private Integer allItemCount;
		/**
		 * 完成率
		 */
		private float finishRate;
		public Integer getUnfinishedItemCount() {
			return unfinishedItemCount;
		}
		public Integer getFinishedItemCount() {
			return finishedItemCount;
		}
		public Integer getAllItemCount() {
			return allItemCount;
		}
		public float getFinishRate() {
			return finishRate;
		}
		public void setUnfinishedItemCount(Integer unfinishedItemCount) {
			this.unfinishedItemCount = unfinishedItemCount;
		}
		public void setFinishedItemCount(Integer finishedItemCount) {
			this.finishedItemCount = finishedItemCount;
		}
		public void setAllItemCount(Integer allItemCount) {
			this.allItemCount = allItemCount;
		}
		public void setFinishRate(float finishRate) {
			this.finishRate = finishRate;
		}
		public InspectionStation getStation() {
			return station;
		}
		public void setStation(InspectionStation station) {
			this.station = station;
		}
	}

	public PlanDetailDTO getPlanDto() {
		return planDto;
	}

	public void setPlanDto(PlanDetailDTO planDto) {
		this.planDto = planDto;
	}

	public List<InspectionStationDTO> getFinishStationDtos() {
		return finishStationDtos;
	}

	public void setFinishStationDtos(List<InspectionStationDTO> finishStationDtos) {
		this.finishStationDtos = finishStationDtos;
	}

	public List<InspectionStationDTO> getUnfinishStationDtos() {
		return unfinishStationDtos;
	}

	public void setUnfinishStationDtos(List<InspectionStationDTO> unfinishStationDtos) {
		this.unfinishStationDtos = unfinishStationDtos;
	}

	public List<InspectionStationDTO> getAllStationDtos() {
		return allStationDtos;
	}

	public void setAllStationDtos(List<InspectionStationDTO> allStationDtos) {
		this.allStationDtos = allStationDtos;
	}

}
